<!DOCTYPE html>
<html>
<head>
<!--
	Copyright (c) 2015-2018 Jean-Marc VIGLINO, 
	released under CeCILL-B (french BSD like) licence: http://www.cecill.info/
-->
	<title>ol-ext: IDW layer</title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1" />
  <link rel="icon" type="image/png" href="https://openlayers.org/assets/theme/img/logo70.png" />

	<meta name="description" content="IDW source for ol" />
	<meta name="keywords" content="ol, openlayers, layer, source, IDW, Inverse Distance Weighting" />

  <meta name="twitter:image" content="https://viglino.github.io/ol-ext/img/map.layer.idw.jpg" />
  <meta name="twitter:site" content="@viglino" />
  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="ol-ext: IDW source" />
  <meta name="twitter:description" content="An Inverse distance weighting (IDW) source for multivariate interpolation with a known scattered set of points on Openlayers maps." />

	<!-- jQuery -->
	<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>

	<!-- Openlayers -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@latest/ol.css" />
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ol@latest/dist/ol.js"></script>
  
	<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
	
	<!-- ol-ext -->
  <link rel="stylesheet" href="../../dist/ol-ext.css" />
  <script type="text/javascript" src="../../dist/ol-ext.js"></script>
  <!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
  <script src="https://unpkg.com/elm-pep"></script>

  <!-- filesaver-js -->
	<script type="text/javascript" src="https://cdn.rawgit.com/eligrey/FileSaver.js/aa9f4e0e/FileSaver.min.js"></script>

	<link rel="stylesheet" href="../style.css" />
  <style>
    #map {
      width: 600px; 
      height: 400px;
      max-width: 100%;
    }
    .fullscreen #map {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
    }
    .fullscreen .options {
      position: absolute;
      left: 50%;
      top: 0;
      transform: translateX(-50%);
      margin: 0;
    }
    .fullscreen .icss-github-corner {
      font-size: 1.5em;
    }
  </style>
</head>
<body >
	<a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a>

	<a href="../../index.html">
		<h1>ol-ext: IDW layer</h1>
	</a>
	<div class="info">
    <p>
      <i>ol/source/IDW</i> is an Inverse Distance Weighting (IDW) interpolated source that use the
      <a href="https://en.wikipedia.org/wiki/Inverse_distance_weighting">Shepard's method</a>.
      <br/>
      The default weight convertion function converts values from 0 (blue) to 100 (red). 
      You can use values up to 128 (magenta). Upper values turn around the color wheel.
      <br/>
      The <i>worker</i> option let you calculate the distance map in a worker.
    </p>
    <ul>
    </ul>
  </div>

	<!-- DIV pour la carte -->
	<div id="map"></div>
	<div class="options">
    Click on the map to add a new measure.
    <br/> Value:
    <input id="value" type="number" value="50" min="0" max="100" />
    <label><input id="random" type="checkbox" checked="checked" /> random</label>
    <button onclick="idw.getSource().clear()">clear</button>
    <button onclick="$('body').toggleClass('fullscreen'); map.updateSize()">FullScreen</button>
	</div>
	
  <script type="text/javascript">
  // The map
	var map = new ol.Map ({
    target: 'map',
    view: new ol.View ({
      zoom: 3,
      center: [261204.43490751847, 6250258.191535994]
    }),
    layers: [ new ol.layer.Geoportail({ layer: 'GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2' })]
  });

  map.addControl(new ol.control.LayerSwitcher());

  // IDW source
  var idw = new ol.source.IDW({
    /* Use workers * /
    useWorker: true,
    lib: {
      // A set of function accessible in the worker
      hue2rgb: function(h) {
        h = (h + 6) % 6;
        if (h < 1) return Math.round(h * 255);
        if (h < 3) return 255;
        if (h < 4) return Math.round((4 - h) * 255);
        return 0;
      }
    },
    getColor: function(v) {
      // Get hue
      var h = 4 - (0.04 * v);
      // Convert to RGB
      return [
        hue2rgb(h + 2),
        hue2rgb(h),
        hue2rgb(h - 2),
        255
      ];
    },
    /**/
    // scale: 8,
    // Source that contains the data
    source: new ol.source.Vector(),
    // Use val as weight property
    weight: 'val'
  });
  map.addLayer (new ol.layer.Image({
    title: 'IDW',
    source: idw,
    opacity: .5
  }));

  map.addLayer(new ol.layer.Vector({
    title: 'source',
    source: idw.getSource(),
    style: function(f) {
      return new ol.style.Style({
        // image: new ol.style.Circle({ radius: 2, fill: new ol.style.Fill({ color: '#000' }) }),
        text: new ol.style.Text({
          text: f.get('val').toString(),
          stroke: new ol.style.Stroke({ color: [255,255,255,128], width: 1.25 }),
        })
      });
    }
  }))

  var draw = new ol.interaction.Draw({ type: 'Point', source: idw.getSource() });
  draw.on('drawend', function(e) {
    e.feature.set('val', parseInt($('#value').val()));
    if ($('#random').prop('checked')) $('#value').val(Math.round(Math.random()*100));
  })
  map.addInteraction(draw);

  // Add a set of features
  function addFeatures(size) {
    size = size || 100;
    var ext = map.getView().calculateExtent();
    var dx = ext[2]-ext[0];
    var dy = ext[3]-ext[1];
    var features = [];
    for (var i=0; i<size; ++i){
      var f = new ol.Feature(new ol.geom.Point([
        ext[0]+dx*Math.random(), 
        ext[1]+dy*Math.random()
      ]));
      f.set('val', Math.round(Math.random()*100));
      features.push(f);
    }
    idw.getSource().addFeatures(features)
  }

	</script>
</body>
</html>